package com.yanqu.road.server.manger.activity;

import com.yanqu.road.entity.activity.ActivityConditionInfo;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.UserActivityConditionData;
import com.yanqu.road.entity.config.goods.MallInfo;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.task.args.RelationActivityUnionRiseRankArgs;
import com.yanqu.road.entity.task.args.UnionRiseRankArgs;
import com.yanqu.road.logic.bussiness.player.UserRelationActivityBussiness;
import com.yanqu.road.server.manger.activity.chefduel.ChefDuelActivityMgr;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.pb.cookboyactivity.CookBoyActivityProto;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.RelationActivityModule;
import com.yanqu.road.server.manger.activity.cookboy.CookBoyActivityMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.RandomHelper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


//全程需要触发活动条件公共类
public class RelationActivityMgr extends TempMgr {

    //触发条件定义
    public static int EVENT_RANK_USER_TYPE = 1;//个人通用排行榜触发条件
    public static int EVENT_RANK_UNION_TYPE = 2;//商会通用排行榜触发条件

    protected static RandomHelper randomHelper = new RandomHelper();

    protected static Logger logger = LogManager.getLogger(RelationActivityMgr.class.getName());

    //对应事件要触发的所有condition类型 activityId,playerEventType,RelationActivityMgrEventType,playerEventType,触发事件可能会一样，加上活动
    protected static Map<Integer,Map<Integer,Map<Integer,Integer>>> eventRelationMap = new ConcurrentHashMap<>();

    //活动对应的排行榜事件activityId RelationActivityMgrEventType conditonType
    protected static Map<Integer,Map<Integer,Integer>> rankEventMap = new ConcurrentHashMap<>();

    protected static Map<Integer,ActivityInfo> activityInfoMap = new ConcurrentHashMap<>();

    //activityId type?
    protected static Map<Integer, Map<Integer, List<ActivityConditionInfo>>> activityConditionInfoMap = new ConcurrentHashMap<>();

    //activityId mallId
    protected static Map<Integer,Map<Integer, MallInfo>> activityMallInfoMap = new ConcurrentHashMap<>();

    //activityId userId type condition 用户不在线也要触发非商会condition
    protected static Map<Integer,Map<Long, Map<Integer,List<UserActivityConditionData>>>> userConditionDataMap = new ConcurrentHashMap<>();

    //子类重写
    public static void addChildEvent(List<ActivityInfo> activityInfoList){

    }

    protected static void addEventRelationMap(int activityId,Map<Integer,Map<Integer,Integer>> eventIdMap){
        eventRelationMap.put(activityId,eventIdMap);
    }

    protected static void addRankEventMap(int activityId,Map<Integer,Integer> reMap){
        rankEventMap.put(activityId,reMap);
    }

    public static int getRankEvent(int activityId,int rankType){
        if(rankEventMap.containsKey(activityId)){
            Map<Integer,Integer> typeEventMap = rankEventMap.get(activityId);
            return typeEventMap.getOrDefault(rankType,0);
        }
        return 0;
    }

    public static void conditionNotify(Integer activityId,long userId,int event,Object object){
        GamePlayer gamePlayer = GamePlayerMgr.getOnlinePlayer(userId);
        if(gamePlayer != null){
            gamePlayer.getModule(RelationActivityModule.class).beginChanges();
            gamePlayer.notifyListener(event,object);
            gamePlayer.getModule(RelationActivityModule.class).commitChanges();
        }else{
            UnionRiseRankArgs args = (UnionRiseRankArgs) object;
            if(null != args) {
                synchronized (userConditionDataMap){
                    List<UserActivityConditionData> tempList = new ArrayList<>();
                    Map<Integer,Integer> eventIdMap = new ConcurrentHashMap<>();
                    if(eventRelationMap.get(activityId).containsKey(event)){
                        eventIdMap = eventRelationMap.get(activityId).get(event);
                        for(int eventId : eventIdMap.values()){
                            if(userConditionDataMap.get(activityId).containsKey(userId)){
                                if(userConditionDataMap.get(activityId).get(userId).containsKey(eventId)){
                                    tempList.addAll(userConditionDataMap.get(activityId).get(userId).get(eventId));
                                }
                            }
                        }
                    }else{
                        if(userConditionDataMap.get(activityId).containsKey(userId)){
                            if(userConditionDataMap.get(activityId).get(userId).containsKey(event)){
                                tempList.addAll(userConditionDataMap.get(activityId).get(userId).get(event));
                            }
                        }
                        eventIdMap.put(EVENT_RANK_USER_TYPE,event);
                    }

                    int conditionType = eventIdMap.getOrDefault(EVENT_RANK_UNION_TYPE, 0);

                    ActivityInfo activityInfo = RelationActivityMgr.getOpenActivityInfo(activityId);
                    boolean noFindUser = true;
                    for(UserActivityConditionData data : tempList){
                        if(data.getActivityId() == activityId){
                            if(eventIdMap.getOrDefault(EVENT_RANK_UNION_TYPE,0) == data.getType()){
                                data.setValue(data.getValue().add(args.getValue()));
                                if(!ActivityMgr.activityOverEndTime(activityInfo)){
                                    if (UnionRiseRankArgs.NOTIFY_TYPE_NORMAL == args.getType() || UnionRiseRankArgs.NOTIFY_TYPE_JOIN == args.getType()) {
                                        data.setUnionUid(args.getUnionUid());
                                    } else if (UnionRiseRankArgs.NOTIFY_TYPE_REMOVE == args.getType() || UnionRiseRankArgs.NOTIFY_TYPE_DELETE == args.getType()) {
                                        data.setUnionUid("");
                                    }
                                    if (UnionRiseRankArgs.NOTIFY_TYPE_DELETE == args.getType()) {//解散商会
                                        RelationActivityRankMgr.removeUnionActivityRank(data.getActivityId(), args.getUnionUid());
                                    }
                                }
                                RelationActivityRankMgr.changeUnionActivityValue(data.getActivityId(), args.getUnionUid(), userId, data, args.getType());
                                noFindUser = false;
                            }else if(eventIdMap.getOrDefault(EVENT_RANK_USER_TYPE,0) == data.getType()){
                                if(data.getType() == eGamePlayerEventType.CookBoy1IntegralServerCrossRank.getValue()){
                                    data.setValue(args.getValue());
                                }else{
                                    data.setValue(data.getValue().add(args.getValue()));
                                    if(data.getValue().compareTo(BigInteger.ZERO) > 0){
                                        RelationActivityRankMgr.changeRank(activityId, UserMgr.getUserInfo(userId), data.getValue());
                                    }
                                }
                            }
                        }
                    }
                    if (noFindUser && conditionType != 0) {
                        RelationActivityRankMgr.changeUnionActivityValue(activityId, args.getUnionUid(), conditionType, args.getType());
                    }

                }
            }
        }
    }

    public static ActivityInfo getActivityInfo(int activityId) {
        return activityInfoMap.get(activityId);
    }

    public static ActivityInfo getActivityInfo(int type ,int childType) {
        for(ActivityInfo activityInfo : activityInfoMap.values()){
            if(activityInfo.getType() == type && activityInfo.getChildType() == childType){
                return activityInfo;
            }
        }
        return null;
    }

    @Override
    public boolean stop() {
        return false;
    }

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean save() {
        synchronized (userConditionDataMap){
            for(Map<Long, Map<Integer,List<UserActivityConditionData>>> allUserDataMap : userConditionDataMap.values()){
                for(Map<Integer,List<UserActivityConditionData>> userDataMap : allUserDataMap.values()){
                    for (List<UserActivityConditionData> conditionList: userDataMap.values()){
                        for(UserActivityConditionData condition : conditionList){
                            if(condition.isInsertOption()){
                                UserRelationActivityBussiness.addUserActivityConditionData(condition);
                            }else if(condition.isUpdateOption()){
                                UserRelationActivityBussiness.updateUserActivityConditionData(condition);
                            }
                        }
                    }
                }
            }
        }
        return true;
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        return true;
    }

    //添加新的活动条件
    public static void addUserActivityConditionData(long userId,UserActivityConditionData userConditionData){
        int activityId = userConditionData.getActivityId();
        synchronized (userConditionDataMap){
            if(!userConditionDataMap.containsKey(activityId)){
                userConditionDataMap.put(activityId,new ConcurrentHashMap<>());
            }
            if(!userConditionDataMap.get(activityId).containsKey(userId)){
                userConditionDataMap.get(activityId).put(userId,new ConcurrentHashMap<>());
            }
            if(!userConditionDataMap.get(activityId).get(userId).containsKey(userConditionData.getType())){
                userConditionDataMap.get(activityId).get(userId).put(userConditionData.getType(),new ArrayList<>());
            }
            userConditionDataMap.get(activityId).get(userId).get(userConditionData.getType()).add(userConditionData);
        }
    }

    public static void reloadActivityData(Map<Integer, ActivityInfo> selectActivityInfoMap, Map<Integer, Map<Integer, MallInfo>> selectActivityMallInfoMap,
                                          Map<Integer, Map<Integer, List<ActivityConditionInfo>>> selectActivityConditionInfoMap){
        logger.info("reload RelationActivityMgr start");
        Map<Integer,Map<Integer, List<ActivityConditionInfo>>> inTimeActivityConditionInfoMap = new ConcurrentHashMap<>();
        Map<Integer,ActivityInfo> inTimeActivityMap = new ConcurrentHashMap<>();
        Map<Integer,Map<Integer, MallInfo>> inTimeActivityMallInfoMap = new ConcurrentHashMap<>();

        for(ActivityInfo activityInfo : selectActivityInfoMap.values()){
            if(ActivityMgr.activityInShowTime(activityInfo)){
                if(!inTimeActivityMap.containsKey(activityInfo.getActivityId())){
                    inTimeActivityMap.put(activityInfo.getActivityId(),activityInfo);
                }
                if(null != selectActivityConditionInfoMap.get(activityInfo.getActivityId())) {
                    inTimeActivityConditionInfoMap.put(activityInfo.getActivityId(), selectActivityConditionInfoMap.get(activityInfo.getActivityId()));
                }
                if(null != selectActivityMallInfoMap.get(activityInfo.getActivityId())){
                    inTimeActivityMallInfoMap.put(activityInfo.getActivityId(),selectActivityMallInfoMap.get(activityInfo.getActivityId()));
                }
            }
        }
        Map<Integer,ActivityInfo> oldActivityInfoMap = activityInfoMap;
        activityInfoMap = inTimeActivityMap;
        activityConditionInfoMap = inTimeActivityConditionInfoMap;
        activityMallInfoMap = inTimeActivityMallInfoMap;
        for(ActivityInfo activityInfo : activityInfoMap.values()){
            //防止刷新活动的时候用户condition被重新加载，用户身上的condition不能重复加载
            if(oldActivityInfoMap.get(activityInfo.getActivityId()) == null ){
                userConditionDataMap.put(activityInfo.getActivityId(),UserRelationActivityBussiness.getUserActivityConditionDataMap(activityInfo.getActivityId()));
            }
        }

        //子类加载子类的逻辑
        CookBoyActivityMgr.reloadActivityData();
        ChefDuelActivityMgr.reloadActivityData();

        RelationActivityRankMgr.reloadRank();
        logger.info("reload RelationActivityMgr end");

        notifyCrossReload();
    }

    private static void notifyCrossReload(){
        //serverId activityId
        Map<Long,Integer> activityIdList = new ConcurrentHashMap<>();
        logger.info("notify CrossRelationActivityMgr reload");
        //通知跨服重新加载活动
        for(ActivityInfo activityInfo :activityInfoMap.values()){
            if(activityIdList.containsKey(activityInfo.getCrossId())){
                continue;
            }
            activityIdList.put(activityInfo.getCrossId(),activityInfo.getActivityId());
        }

        for(int activityId : activityIdList.values()){
            CookBoyActivityProto.CrossRelationActivityReloadMsg.Builder msg = CookBoyActivityProto.CrossRelationActivityReloadMsg.newBuilder();
            msg.setActivityId(activityId);
            YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_RELATION_ACTIVITY_RELOAD, msg);
            GamePlayerMgr.sendPacket(0, pbMsg);
        }
    }


    public static ActivityInfo getOpenActivityInfo(int activityId){
        if(!activityInfoMap.containsKey(activityId)){
            return null;
        }
        ActivityInfo activityInfo = activityInfoMap.get(activityId);
        if(ActivityMgr.activityInShowTime(activityInfo) && activityInfo.getActivityId() == activityId){
            return activityInfo;
        }
        return null;
    }

    public static boolean isActivityOver(ActivityInfo activityInfo){
        if(ActivityMgr.activityOver(activityInfo)){
            return true;
        }
        return false;
    }

    public static ActivityInfo getInTimeActivityInfo(int activityId){
        if(!activityInfoMap.containsKey(activityId)){
            return null;
        }
        ActivityInfo activityInfo = activityInfoMap.get(activityId);
        if(ActivityMgr.activityInTime(activityInfo) && activityInfo.getActivityId() == activityId){
            return activityInfo;
        }
        return null;
    }

    public static boolean isActivityContain(ActivityInfo activityInfo1,ActivityInfo activityInfo2){
        if(null == activityInfo1 || null == activityInfo2){
            return false;
        }
        long nowTime = System.currentTimeMillis() / 1000;
        return activityInfo2.getEndShowTime() > activityInfo1.getBeginShowTime() && activityInfo2.getBeginShowTime() < activityInfo1.getEndShowTime();
    }

    public static List<ActivityInfo> getOpenActivityInfoList() {
        List<ActivityInfo> dataList = new ArrayList<>();
        for(ActivityInfo activityInfo : activityInfoMap.values()) {
            if (ActivityMgr.activityInShowTime(activityInfo)) {
                dataList.add(activityInfo);
            }
        }
        return dataList;
    }

    public static List<ActivityInfo> getOpenActivityInfoList(int type) {
        List<ActivityInfo> dataList = new ArrayList<>();
        for(ActivityInfo activityInfo : activityInfoMap.values()) {
            if(activityInfo.getType() == type){
                if (ActivityMgr.activityInShowTime(activityInfo)) {
                    dataList.add(activityInfo);
                }
            }
        }
        return dataList;
    }

    public static List<ActivityInfo> getOpenActivityInfoList(int type,int childType) {
        List<ActivityInfo> dataList = new ArrayList<>();
        for(ActivityInfo activityInfo : activityInfoMap.values()) {
            if(activityInfo.getType() == type && activityInfo.getChildType() == childType){
                if (ActivityMgr.activityInShowTime(activityInfo)) {
                    dataList.add(activityInfo);
                }
            }
        }
        return dataList;
    }

    public static Map<Integer,ActivityInfo> getOpenActivityInfoMap(int type) {
        Map<Integer,ActivityInfo> dataMap = new ConcurrentHashMap<>();
        for(ActivityInfo activityInfo : activityInfoMap.values()) {
            if(activityInfo.getType() == type){
                if (ActivityMgr.activityInShowTime(activityInfo)) {
                    dataMap.put(activityInfo.getActivityId(),activityInfo);
                }
            }
        }
        return dataMap;
    }

    public static MallInfo getMallInfo(int activityId,int mallId){
        MallInfo mallInfo;
        if(activityMallInfoMap.containsKey(activityId)){
            if(activityMallInfoMap.get(activityId).containsKey(mallId)){
                return activityMallInfoMap.get(activityId).get(mallId);
            }
        }
        return null;
    }

    public static MallInfo getMallInfo(int mallId){
        MallInfo mallInfo;
        for(Map<Integer, MallInfo> mallInfoMap : activityMallInfoMap.values()){
            mallInfo = mallInfoMap.get(mallId);
            if(null != mallInfo){
                return mallInfo;
            }
        }
        return null;
    }

    public static List<MallInfo> getActivityMallInfoListByCategory(int category){
        List<MallInfo> dataList = new ArrayList<>();
        for (ActivityInfo activityInfo : activityInfoMap.values()) {
            Map<Integer, MallInfo> tempMallMap = activityMallInfoMap.get(activityInfo.getActivityId());
            if (null != tempMallMap) {
                for (MallInfo mallInfo : tempMallMap.values()) {
                    if (mallInfo.getCategory() == category) {
                        dataList.add(mallInfo);
                    }
                }
            }
        }
        return dataList;
    }

    public static List<ActivityConditionInfo> getActivityConditionInfoList(int activityId, int contidionType){
        ActivityInfo openActivityInfo = getOpenActivityInfo(activityId);
        if(null != openActivityInfo) {
            return activityConditionInfoMap.get(activityId).get(contidionType);
        }
        return null;
    }

    public static ActivityConditionInfo getActivityConditionInfoByRank(int activityId, int conditionType, int rank) {
        List<ActivityConditionInfo> dataList = getActivityConditionInfoList(activityId, conditionType);
        if(null != dataList) {
            for (ActivityConditionInfo conditionInfo : dataList) {
                if (rank >= conditionInfo.getParamList().get(0).intValue() && rank <= conditionInfo.getParamList().get(1).intValue()) {
                    return conditionInfo;
                }
            }
        }
        return null;
    }

    public static ActivityConditionInfo getActivityConditionInfo(int activityId, int conditionId) {
        if(activityConditionInfoMap.containsKey(activityId)){
            for (List<ActivityConditionInfo> conditionInfoList : activityConditionInfoMap.get(activityId).values()) {
                for (ActivityConditionInfo conditionInfo : conditionInfoList) {
                    if (conditionId == conditionInfo.getConditionId()) {
                        return conditionInfo;
                    }
                }
            }
        }
        return null;
    }

    public static int getMaxRankByType(int activityId, int conditionType) {
        int maxRank = 0;
        List<ActivityConditionInfo> dataList = getActivityConditionInfoList(activityId, conditionType);
        if(null != dataList) {
            for (ActivityConditionInfo conditionInfo : dataList) {
                if (conditionInfo.getParamList().get(1).intValue() > maxRank) {
                    maxRank = conditionInfo.getParamList().get(1).intValue();
                }
            }
        }
        return maxRank;
    }


    public static Map<Integer, List<ActivityConditionInfo>> getActivityConditionInfoMap(int activityId) {
        ActivityInfo inTimeActivityInfo = getOpenActivityInfo(activityId);
        if(null != inTimeActivityInfo) {
            return activityConditionInfoMap.get(activityId);
        }
        return null;
    }


    //返回用户的condition
    public static Map<Integer, List<UserActivityConditionData>> getUserActivityConditionDataMap(long userId,int activityId){
        if(userConditionDataMap.containsKey(activityId)){
            if(userConditionDataMap.get(activityId).containsKey(userId)){
                return userConditionDataMap.get(activityId).get(userId);
            }
        }
        return null;
    }
    public static BigInteger getUserActivityConditionValue(int activityId,int type){
        if(eGamePlayerEventType.CookBoy1IntegralServerCrossRank.getValue() == type){
            BigInteger value = BigInteger.ZERO;
            if(userConditionDataMap.containsKey(activityId)){
                Map<Long, Map<Integer,List<UserActivityConditionData>>> userMap = new ConcurrentHashMap<>(userConditionDataMap.get(activityId));
                for(Map<Integer,List<UserActivityConditionData>> cMap : userMap.values()){
                    if(cMap.containsKey(eGamePlayerEventType.CookBoy1IntegralUserCrossRank.getValue())){
                        UserActivityConditionData c = cMap.get(eGamePlayerEventType.CookBoy1IntegralUserCrossRank.getValue()).get(0);
                        value = value.add(c.getValue());
                    }
                }
            }
            return value;
        }
        return BigInteger.ZERO;
    }

    public static void notifyServerValue(int activityId,BigInteger value){
        if(userConditionDataMap.containsKey(activityId)){
            List<Long> userIdList = new ArrayList<>(userConditionDataMap.get(activityId).keySet());
            for(long userId : userIdList){
                RelationActivityMgr.conditionNotify(activityId,userId, eGamePlayerEventType.CookBoy1IntegralServerCrossRank.getValue(),
                        new RelationActivityUnionRiseRankArgs(UnionRiseRankArgs.NOTIFY_TYPE_NORMAL, value,"", activityId));
            }
        }
    }

    public static UserActivityConditionData getUserActivityCondition(long userId,int activityId,int conditionId){
        ActivityConditionInfo activityConditionInfo = getActivityConditionInfo(activityId,conditionId);
        if(activityConditionInfo != null){
            if(userConditionDataMap.containsKey(activityId)){
                if(userConditionDataMap.get(activityId).containsKey(userId)){
                    List<UserActivityConditionData> userActivityConditionDataList = userConditionDataMap.get(activityId).get(userId).get(activityConditionInfo.getType());
                    for(UserActivityConditionData userActivityConditionData : userActivityConditionDataList){
                        if(userActivityConditionData.getConditionId() == conditionId){
                            return userActivityConditionData;
                        }
                    }
                }
            }

        }
        return null;
    }

    public static Map<Integer, MallInfo> getActivityAllMall(int activityId){
        return activityMallInfoMap.get(activityId);
    }
}
